home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //
- // ControlUnit.cxx - Control Unit for the Hector 1600 CPU
- // (behavioral level)
- //
- // By: Bradford W. Mott
- // December 4,1993
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- #include "ControlUnit.hxx"
- #include "Tools.hxx"
-
- ///////////////////////////////////////////////////////////////////////////////
- // Execute the next instruction
- ///////////////////////////////////////////////////////////////////////////////
- const char* ControlUnit::ExecuteInstruction(String& trace_record,
- int trace_flag)
- {
- const char *error_message;
-
- // Reset the Data Path Signals
- data_path.ResetSignals();
-
- // Added the Instruction Address field to the trace_record if tracing
- if(trace_flag)
- {
- trace_record+="{InstructionAddress {";
- trace_record+=IntToString(data_path.register_set.GetRegister(PC), 4);
- trace_record+="}}";
- }
-
- // Fetch the next instruction and put it in IR
- data_path.a_sel(PC);
- data_path.mar_sel(A_BUS);
- data_path.mar_latch();
- data_path.mar_out_en();
- data_path.ir_latch();
- data_path.alu_fn(INC_A_NCC);
- data_path.alu_gt();
- data_path.wrt_a();
- if(( error_message = data_path.Clock() ) != (void*)0)
- return(error_message);
-
- error_message=DecodeAndExecute(trace_flag);
-
- // If there wasn't an error then add the mnemonic to the trace_record
- if((error_message == (void*)0) && trace_flag)
- {
- mnemonic+="}}";
- trace_record+=" ";
- trace_record+=mnemonic;
- }
-
- return(error_message);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // Decode the instruction in the IR register and execute it
- ///////////////////////////////////////////////////////////////////////////////
- const char* ControlUnit::DecodeAndExecute(int trace_flag)
- {
- const char* error_message;
- int dm = (data_path.ir & 0x0300) >> 8; // Destination Mode field
- int sm = (data_path.ir & 0x0c00) >> 10; // Source Mode field
-
-
- // Setup the mnemonic trace entry
- if(trace_flag)
- mnemonic="{Mnemonic {";
-
- switch ((data_path.ir & 0xf000) >> 12)
- {
- case 0: // ADD
- if(trace_flag) mnemonic+="ADD ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 1: // ADDC
- if(trace_flag) mnemonic+="ADDC ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 2: // SUB
- if(trace_flag) mnemonic+="SUB ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 3: // AND
- if(trace_flag) mnemonic+="AND ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 4: // SUBC
- if(trace_flag) mnemonic+="SUBC ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 5: // OR
- if(trace_flag) mnemonic+="OR ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 6: // XOR
- if(trace_flag) mnemonic+="XOR ";
- error_message=ExecuteGroup1(trace_flag);
- break;
-
- case 7: // Stop
- error_message="STOP instruction";
- break;
-
- case 8: // NOT, NEG, INC, DEC
- switch (dm)
- {
- case 0: // NOT
- if(trace_flag) mnemonic+="NOT ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- case 1: // NEG
- if(trace_flag) mnemonic+="NEG ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- case 2: // INC
- if(trace_flag) mnemonic+="INC ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- case 3: // DEC
- if(trace_flag) mnemonic+="DEC ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- }
- break;
-
- case 9: // SHL, ROL, SHR, ROR
- switch (dm)
- {
- case 0: // SHL
- if(trace_flag) mnemonic+="SHL ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- case 1: // ROL
- if(trace_flag) mnemonic+="ROL ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- case 2: // SHR
- if(trace_flag) mnemonic+="SHR ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- case 3: // ROR
- if(trace_flag) mnemonic+="ROR ";
- error_message=ExecuteGroup2(trace_flag);
- break;
- }
- break;
-
- case 10: // CMP
- if(trace_flag) mnemonic+="CMP ";
- error_message=ExecuteGroup3(trace_flag);
- break;
-
- case 11: // BTST
- if(trace_flag) mnemonic+="BTST ";
- error_message=ExecuteGroup3(trace_flag);
- break;
-
- case 12: // BRA, JSR, SWAP, CLR
- switch (dm)
- {
- case 0: // BRA
- if(trace_flag) mnemonic+="BRA ";
- error_message=ExecuteBRA(trace_flag);
- break;
- case 1: // JSR
- if(trace_flag) mnemonic+="JSR ";
- error_message=ExecuteJSR(trace_flag);
- break;
- case 2: // SWAP
- if(trace_flag) mnemonic+="SWAP ";
- error_message=ExecuteSWAP(trace_flag);
- break;
- case 3: // CLR
- if(trace_flag) mnemonic+="CLR ";
- error_message=ExecuteCLR(trace_flag);
- break;
- }
- break;
-
- case 13: // MOVE
- if(trace_flag) mnemonic+="MOVE ";
- error_message=ExecuteMOVE(trace_flag);
- break;
-
- case 14: // TEST, STF, LDF, PUSH
- switch (dm)
- {
- case 0: // TEST
- if(trace_flag) mnemonic+="TEST ";
- error_message=ExecuteTEST(trace_flag);
- break;
- case 1: // STF
- if(trace_flag) mnemonic+="STF ";
- error_message=ExecuteSTF(trace_flag);
- break;
- case 2: // LDF
- if(trace_flag) mnemonic+="LDF ";
- error_message=ExecuteLDF(trace_flag);
- break;
- case 3: // PUSH
- if(trace_flag) mnemonic+="PUSH ";
- error_message=ExecutePUSH(trace_flag);
- break;
- }
- break;
-
- case 15: // SEC, CLC, SEI, CLI, RTI, SWI, EXCH, SRCH
- switch (sm)
- {
- case 0: // SEC, CLC, SEI, CLI
- switch (dm)
- {
- case 0: // SEC
- if(trace_flag) mnemonic+="SEC ";
- error_message=ExecuteSEC(trace_flag);
- break;
- case 1: // CLC
- if(trace_flag) mnemonic+="CLC ";
- error_message=ExecuteCLC(trace_flag);
- break;
- case 2: // SEI
- if(trace_flag) mnemonic+="SEI ";
- error_message=ExecuteSEI(trace_flag);
- break;
- case 3: // CLI
- if(trace_flag) mnemonic+="CLI ";
- error_message=ExecuteCLI(trace_flag);
- break;
- }
- break;
- case 1: // RTI, SWI, EXCH, SRCH
- switch (dm)
- {
- case 0: // RTI
- if(trace_flag) mnemonic+="RTI ";
- error_message=ExecuteRTI(trace_flag);
- break;
- case 1: // SWI
- if(trace_flag) mnemonic+="SWI ";
- error_message=ExecuteSWI(trace_flag);
- break;
- case 2: // EXCH
- if(trace_flag) mnemonic+="EXCH ";
- error_message=ExecuteEXCH(trace_flag);
- break;
- case 3: // SRCH
- if(trace_flag) mnemonic+="SRCH ";
- error_message=ExecuteSRCH(trace_flag);
- break;
- }
- break;
- }
- break;
-
- default:
- error_message="Illegal Opcode";
- break;
- }
- return(error_message);
- }
-